
use super::hittable::*;
use super::super::ray::Ray;

pub struct HittableList {
    objects: Vec<Box<dyn Hittable>>
}

impl HittableList {
    pub fn new() -> Self {
        Self{ objects:vec![] }
    }

    pub fn add<T: Hittable+'static>(&mut self, obj:T) {
        self.objects.push(Box::new(obj));
    }

    pub fn clear(&mut self) {
        self.objects.clear();
    }
}

impl Hittable for HittableList {
    fn hit(&self, r: &Ray, t_min: f32, t_max:f32, rec: &mut HitRecord) -> bool {
        let mut temp_rec = HitRecord::default();
        let mut hit_anything = false;
        let mut closest_so_far = t_max;

        for obj in self.objects.iter() {
            if obj.hit(&r, t_min, closest_so_far, &mut temp_rec) {
                hit_anything = true;
                closest_so_far = temp_rec.get_t();
                *rec = temp_rec;
            }
            temp_rec = HitRecord::default();
        }

        return hit_anything;
    }
}